﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Atmk.WaterMeter.MIS.Commons.ViewModels.District;
using Common.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Ninject.Syntax;

namespace Atmk.WaterMeter.MIS.TestForm.Common.Utils
{
    /// <summary>
    /// json绑定到TreeView控件
    /// </summary>
    public class JsonTreeViewHelper
    {
        private static readonly ILog _Logger = LogManager.GetLogger<JsonTreeViewHelper>();

        /// <summary>
        /// 绑定树形控件
        /// </summary>
        /// <param name="treeView"></param>
        /// <param name="data"></param>
        public static void BindTreeView(TreeView treeView, DistrictNodesData data)
        {
            treeView.Nodes.Clear();
            var rootNode = new TreeNode("抄表系统");
            treeView.Nodes.Add(rootNode);
            foreach (var area in data.areaList)
            {
                var node = new TreeNode(area.name) {Tag = area};
                var result = FindNode(area.parentId, rootNode);
                if (result == null)
                    rootNode.Nodes.Add(node);
                else
                    result.Nodes.Add(node);
            }
            treeView.ExpandAll();
        }

        private static TreeNode FindNode(string parentId, TreeNode node)
        {
            foreach (TreeNode subNode in node.Nodes)
            {
                if (subNode.Tag is DistrictNode area && area.id == parentId)
                    return subNode;
                if (subNode.Nodes.Count > 0)
                    return FindNode(parentId, subNode);
            }
            return null;
        }

        /// <summary>
        /// 递归算法
        /// </summary>
        /// <param name="upNode"></param>
        /// <param name="pid"></param>
        /// <param name="obj"></param>
        /// <returns></returns>
        private void DepartmentRecursion(TreeNode upNode, string pid, List<DistrictNode> obj)
        {
            for (int i = 0; i < obj.Count; i++)
            {
                var dNode = obj[i];
                if (dNode.parentId == pid)
                {
                    var node = new TreeNode(dNode.name) {Tag = dNode.id};
                    upNode.Nodes.Add(node);
                    DepartmentRecursion(node, dNode.id, obj);
                }
            }
        }

        private static void BindRoot(TreeView treeView, List<DistrictNode> root)
        {
            var nodes = root.Select(r => new TreeNode(r.name) {Tag = r.id}).ToArray();
            treeView.Nodes.AddRange(nodes);
        }

        private static void BindBranch(TreeView treeView, List<DistrictNode> branchs)
        {
            foreach (TreeNode treeViewNode in treeView.Nodes)
            {
                var districtNodes = branchs.Where(b => b.parentId == treeViewNode.Tag.ToString()).ToList();
                var nodes = districtNodes.Select(r => new TreeNode(r.name) {Tag = r.id}).ToArray();
                treeViewNode.Nodes.AddRange(nodes);
            }
        }

        /// <summary>
        /// 绑定树形控件
        /// </summary>
        /// <param name="treeView"></param>
        /// <param name="strJson"></param>
        public static void BindTreeView(TreeView treeView, string strJson)
        {
            treeView.Nodes.Clear();

            if (IsJOjbect(strJson))
            {
                var jo = (JObject) JsonConvert.DeserializeObject(strJson);

                foreach (var item in jo)
                {
                    TreeNode tree;
                    if (item.Value.GetType() == typeof(JObject))
                    {
                        tree = new TreeNode(item.Key);
                        AddTreeChildNode(ref tree, item.Value.ToString());
                        treeView.Nodes.Add(tree);
                    }
                    else if (item.Value.GetType() == typeof(JArray))
                    {
                        tree = new TreeNode(item.Key);
                        AddTreeChildNode(ref tree, item.Value.ToString());
                        treeView.Nodes.Add(tree);
                    }
                    else
                    {
                        tree = new TreeNode(item.Key + ":" + item.Value);
                        treeView.Nodes.Add(tree);
                    }
                }
            }
            if (IsJArray(strJson))
            {
                var ja = (JArray) JsonConvert.DeserializeObject(strJson);
                var i = 0;
                foreach (JObject item in ja)
                {
                    var tree = new TreeNode("Array [" + (i++) + "]");
                    foreach (var itemOb in item)
                    {
                        TreeNode treeOb;
                        if (itemOb.Value.GetType() == typeof(JObject))
                        {
                            treeOb = new TreeNode(itemOb.Key);
                            AddTreeChildNode(ref treeOb, itemOb.Value.ToString());
                            tree.Nodes.Add(treeOb);
                        }
                        else if (itemOb.Value.GetType() == typeof(JArray))
                        {
                            treeOb = new TreeNode(itemOb.Key);
                            AddTreeChildNode(ref treeOb, itemOb.Value.ToString());
                            tree.Nodes.Add(treeOb);
                        }
                        else
                        {
                            treeOb = new TreeNode(itemOb.Key + ":" + itemOb.Value);
                            tree.Nodes.Add(treeOb);
                        }
                    }
                    treeView.Nodes.Add(tree);
                }
            }
            treeView.ExpandAll();
        }

        /// <summary>
        /// 添加子节点
        /// </summary>
        /// <param name="parantNode"></param>
        /// <param name="value"></param>
        public static void AddTreeChildNode(ref TreeNode parantNode, string value)
        {
            if (IsJOjbect(value))
            {
                var jo = (JObject) JsonConvert.DeserializeObject(value);
                try
                {
                    foreach (var item in jo)
                    {
                        TreeNode tree;
                        if (item.Value.GetType() == typeof(JObject))
                        {
                            tree = new TreeNode(item.Key);
                            AddTreeChildNode(ref tree, item.Value.ToString());
                            parantNode.Nodes.Add(tree);
                        }
                        else if (item.Value.GetType() == typeof(JArray))
                        {
                            tree = new TreeNode(item.Key);
                            AddTreeChildNode(ref tree, item.Value.ToString());
                            parantNode.Nodes.Add(tree);
                        }
                        else
                        {
                            tree = new TreeNode(item.Key + ":" + item.Value);
                            parantNode.Nodes.Add(tree);
                        }
                    }
                }
                catch (Exception e)
                {
                    _Logger.Error(e);
                }
            }
            if (!IsJArray(value)) return;
            {
                var ja = (JArray) JsonConvert.DeserializeObject(value);
                var i = 0;
                foreach (var jToken in ja)
                {
                    var item = (JObject) jToken;
                    var tree = new TreeNode("Array [" + (i++) + "]");
                    parantNode.Nodes.Add(tree);
                    foreach (var itemOb in item)
                    {
                        TreeNode treeOb;
                        if (itemOb.Value.GetType() == typeof(JObject))
                        {
                            treeOb = new TreeNode(itemOb.Key);
                            AddTreeChildNode(ref treeOb, itemOb.Value.ToString());
                            tree.Nodes.Add(treeOb);
                        }
                        else if (itemOb.Value.GetType() == typeof(JArray))
                        {
                            treeOb = new TreeNode(itemOb.Key);
                            AddTreeChildNode(ref treeOb, itemOb.Value.ToString());
                            tree.Nodes.Add(treeOb);
                        }
                        else
                        {
                            treeOb = new TreeNode(itemOb.Key + ":" + itemOb.Value);
                            tree.Nodes.Add(treeOb);
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 判断是否JOjbect类型
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        private static bool IsJOjbect(string value)
        {
            try
            {
                JObject.Parse(value);
                _Logger.Info("是JObject类型");
                return true;
            }
            catch (Exception)
            {
                _Logger.Info("不是JObject类型");
                return false;
            }
        }

        /// <summary>
        /// 判断是否JArray类型
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        private static bool IsJArray(string value)
        {
            try
            {
                JArray.Parse(value);
                _Logger.Info("是JArray类型");
                return true;
            }
            catch (Exception)
            {
                _Logger.Info("不是JArray类型");
                return false;
            }
        }
    }
}